<template>
  <div class="page-animate">
    <div class="canvas"></div>
    <div class="controller">
      <el-form label-width="50px">
        <el-button :type="state.axesFlag?'success':'info'" @click="onToggleAxes" style="margin-bottom: 10px">
          坐标轴
        </el-button>
        <el-form-item label="透明度">
          <el-slider class="slider" v-model="state.alpha" :step="0.1" :max="1"/>
        </el-form-item>
        <div class="item">
          <el-button :type="state.animate1Flag?'success':'info'" @click="onToggleAnimate(1)">动画1</el-button>
        </div>
        <div class="item">
          <el-button :type="state.animate2Flag?'success':'info'" @click="onToggleAnimate(2)">动画2</el-button>
        </div>
      </el-form>
    </div>
  </div>
</template>
<script setup>
import * as Three from 'three';
import {onMounted, onUnmounted, reactive, watch} from 'vue';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import gsap from 'gsap';

let state = reactive({
  axesFlag: true,
  taskFlag: true,
  alpha: 0.5,
  animate1Flag: true,
  animate2Flag: true,
});
let scene = new Three.Scene();
let axes = new Three.AxesHelper(5);
let cubeGeometry = new Three.BoxGeometry(1, 1, 1);
let cubeMaterial = new Three.MeshBasicMaterial({color: '#1dd1a1'});
let cube = new Three.Mesh(cubeGeometry, cubeMaterial);
let renderer = new Three.WebGLRenderer({antialias: true, alpha: true});
renderer.setClearColor('#c7ecee');
renderer.setClearAlpha(state.alpha);
function onToggleAxes() {
  state.axesFlag = !state.axesFlag;
  if (!state.axesFlag) {
    scene.remove(axes);
  } else {
    scene.add(axes);
  }
}
watch(() => state.alpha, val => {
  renderer.setClearAlpha(val);
});
// 切换动画播放状态
let animate1, animate2;
function onToggleAnimate(num) {
  if (num == 1) {
    state.animate1Flag ? animate1.pause() : animate1.resume();
    state.animate1Flag = !state.animate1Flag;
  } else if (num == 2) {
    state.animate2Flag ? animate2.pause() : animate2.resume();
    state.animate2Flag = !state.animate2Flag;
  }
}
onMounted(() => {
  let dom = document.getElementsByClassName('canvas')[0];
  let width = dom.clientWidth;
  let height = dom.clientHeight;
  let camera = new Three.PerspectiveCamera(75, width / height, 0.1, 1000);
  camera.position.set(0, 0, 10);
  scene.add(camera);
  scene.add(axes);
  scene.add(cube);
  renderer.setSize(width, height);
  dom.appendChild(renderer.domElement);
  let controller = new OrbitControls(camera, renderer.domElement);
  controller.enableDamping = true;
  // 用gsap创建动画
  animate1 = gsap.to(cube.position, {x: 5, duration: 3, repeat: -1, yoyo: true, ease: 'power1.inOut'});
  animate2 = gsap.to(cube.rotation, {x: Math.PI, duration: 3, repeat: -1, yoyo: true, ease: 'power1.inOut'});
  function render() {
    controller.update();
    renderer.render(scene, camera);
    state.taskFlag && requestAnimationFrame(render);
  }
  render();
});
onUnmounted(() => state.taskFlag = false);
</script>
<style lang="scss">
.page-animate {
  display: flex;
  .canvas {
    flex: 1;
    height: 100%;
    canvas {
      background-color: #fff;
    }
  }
  .controller {
    box-sizing: border-box;
    flex: 0 0 200px;
    height: 100%;
    padding: 10px;
    .title {
      font-weight: 600;
      margin: 10px 0;
      font-size: 14px;
    }
    .el-form-item, .item {
      margin-bottom: 10px;
    }
  }
}
</style>